#include "sphere.h"

#ifdef _WIN32
#include <windows.h>
#endif
#include <glut.h>

using namespace PBVP;

GLSLProgram* Sphere::pGLSLProg = NULL;
bool Sphere::initialized = false;

void Sphere::render()
{
	// render using shaders
	if(pGLSLProg && pGLSLProg->isValid()) {


		return;
	} 
	// render using standard OpenGL
	glPushMatrix();
	glTranslatef(center.x, center.y, center.z);
	glutSolidSphere(radius, 10, 6);
	glPopMatrix();
	// TODO
}

GeometryData* Sphere::toGeometry(unsigned int level)
{
	GeometryData *pGeo = new GeometryData();

	const float X = .525731112119133606;
	const float Z = .850650808352039932;

	float vdata[12][3] = {    
		{-X, 0.0, Z}, {X, 0.0, Z}, {-X, 0.0, -Z}, {X, 0.0, -Z},    
		{0.0, Z, X}, {0.0, Z, -X}, {0.0, -Z, X}, {0.0, -Z, -X},    
		{Z, X, 0.0}, {-Z, X, 0.0}, {Z, -X, 0.0}, {-Z, -X, 0.0} 
	};

	for(int i = 0; i < 12; i++) {
		float x = vdata[i][0]*radius + center.x;
		float y = vdata[i][1]*radius + center.y;
		float z = vdata[i][2]*radius + center.z;
		pGeo->addVertex(x, y, z);
	}
	unsigned int tindices[20][3] = { 
		{0,4,1}, {0,9,4}, {9,5,4}, {4,5,8}, {4,8,1},    
		{8,10,1}, {8,3,10}, {5,3,8}, {5,2,3}, {2,7,3},    
		{7,10,3}, {7,6,10}, {7,11,6}, {11,0,6}, {0,1,6}, 
		{6,1,10}, {9,0,11}, {9,11,2}, {9,2,5}, {7,2,11} 
	};
	for(int i = 0; i < 20; i++) {
		pGeo->addTriangle(tindices[i][0], tindices[i][1], tindices[i][2]);
	}
	// TODO: Add higher-res triangulation by subdivision

	return pGeo;
}

////////////////////////////////////////////////////////////////////
// Static functions
////////////////////////////////////////////////////////////////////
Sphere* Sphere::makeSphere(const Vector3 pnt, double r)
{
	if(pGLSLProg == NULL && !initialized) initGLSLProgram();

	Sphere *pSphere = new Sphere();
	pSphere->radius = r;
	pSphere->center = pnt;
	return pSphere;
}

void Sphere::initGLSLProgram()
{
	initialized = true;
	// TODO
}